﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Brain.Editor
{
#if !WINDOWS_PHONE
    public class PickingManager3D_Color : IPickingManager3D
    {
        private static Color lastPickColor = new Color(0, 0, 0);
        
        public IWorldObject SelectedWorldObject { get; set; }

        public bool Manipulating { get; set; }

        public ManipulationMode3D Mode { get; set; }

        public bool ShouldUpdate { get; set; }
        public bool ShouldDraw { get; set; }

        public event SetWorldObject OnSelected;

        public float ScaleBefore;
        public Vector3 UnitAxis;

#if WINDOWS
        Byte[] effect = new Byte[1620] {207,11,240,188,16,0,0,0,0,0,0,0,0,0,0,0,1,9,255,254,192,1,0,0,0,0,0,0,3,0,0,0,2,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,87,111,114,108,100,0,122,0,3,0,0,0,2,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,86,105,101,119,0,0,0,0,3,0,0,0,2,0,0,0,48,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,80,114,111,106,101,99,116,105,111,110,0,0,3,0,0,0,1,0,0,0,104,1,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,67,111,108,111,114,0,0,0,1,0,0,0,16,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,15,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,80,97,115,115,49,0,0,0,11,0,0,0,84,101,99,104,110,105,113,117,101,49,0,0,4,0,0,0,1,0,0,0,3,0,0,0,3,0,0,0,4,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,108,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,212,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,64,1,0,0,92,1,0,0,0,0,0,0,0,0,0,0,176,1,0,0,0,0,0,0,1,0,0,0,164,1,0,0,0,0,0,0,2,0,0,0,146,0,0,0,0,0,0,0,120,1,0,0,116,1,0,0,147,0,0,0,0,0,0,0,144,1,0,0,140,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0,232,1,0,0,0,2,255,255,254,255,22,0,67,84,65,66,28,0,0,0,35,0,0,0,0,2,255,255,0,0,0,0,0,0,0,0,0,0,0,32,28,0,0,0,112,115,95,50,95,48,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,50,54,46,57,53,50,46,50,56,52,52,0,254,255,93,0,80,82,69,83,1,2,88,70,254,255,36,0,67,84,65,66,28,0,0,0,91,0,0,0,1,2,88,70,1,0,0,0,28,0,0,0,0,1,0,32,88,0,0,0,48,0,0,0,2,0,0,0,1,0,0,0,56,0,0,0,72,0,0,0,67,111,108,111,114,0,171,171,1,0,3,0,1,0,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,120,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,50,54,46,57,53,50,46,50,56,52,52,0,254,255,12,0,80,82,83,73,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,254,255,18,0,67,76,73,84,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,20,0,70,88,76,67,2,0,0,0,3,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,240,240,240,240,15,15,15,15,255,255,0,0,1,0,0,2,0,8,15,128,0,0,228,160,255,255,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,212,1,0,0,0,2,254,255,254,255,63,0,67,84,65,66,28,0,0,0,198,0,0,0,0,2,254,255,3,0,0,0,28,0,0,0,0,0,0,32,191,0,0,0,88,0,0,0,2,0,8,0,4,0,0,0,100,0,0,0,116,0,0,0,180,0,0,0,2,0,4,0,4,0,0,0,100,0,0,0,116,0,0,0,185,0,0,0,2,0,0,0,4,0,0,0,100,0,0,0,116,0,0,0,80,114,111,106,101,99,116,105,111,110,0,171,3,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,105,101,119,0,87,111,114,108,100,0,118,115,95,50,95,48,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,50,54,46,57,53,50,46,50,56,52,52,0,171,31,0,0,2,0,0,0,128,0,0,15,144,9,0,0,3,0,0,1,128,0,0,228,144,0,0,228,160,9,0,0,3,0,0,2,128,0,0,228,144,1,0,228,160,9,0,0,3,0,0,4,128,0,0,228,144,2,0,228,160,9,0,0,3,0,0,8,128,0,0,228,144,3,0,228,160,9,0,0,3,1,0,1,128,0,0,228,128,4,0,228,160,9,0,0,3,1,0,2,128,0,0,228,128,5,0,228,160,9,0,0,3,1,0,4,128,0,0,228,128,6,0,228,160,9,0,0,3,1,0,8,128,0,0,228,128,7,0,228,160,9,0,0,3,0,0,1,192,1,0,228,128,8,0,228,160,9,0,0,3,0,0,2,192,1,0,228,128,9,0,228,160,9,0,0,3,0,0,4,192,1,0,228,128,10,0,228,160,9,0,0,3,0,0,8,192,1,0,228,128,11,0,228,160,255,255,0,0 };
#endif
#if XBOX
        Byte[] effect = new Byte[1380] {188,240,11,207,0,0,0,16,0,0,0,0,0,0,0,0,254,255,9,1,0,0,1,192,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,87,111,114,108,100,0,0,0,0,0,0,3,0,0,0,3,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,86,105,101,119,0,0,0,0,0,0,0,3,0,0,0,3,0,0,1,48,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,80,114,111,106,101,99,116,105,111,110,0,0,0,0,0,3,0,0,0,1,0,0,1,104,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,67,111,108,111,114,0,0,0,0,0,0,1,0,0,0,16,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,15,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,80,97,115,115,49,0,0,0,0,0,0,11,84,101,99,104,110,105,113,117,101,49,0,0,0,0,0,4,0,0,0,1,0,0,0,3,0,0,0,3,0,0,0,4,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,108,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,212,0,0,0,240,0,0,0,0,0,0,0,0,0,0,1,64,0,0,1,92,0,0,0,0,0,0,0,0,0,0,1,176,0,0,0,0,0,0,0,1,0,0,1,164,0,0,0,0,0,0,0,2,0,0,0,92,0,0,0,0,0,0,1,120,0,0,1,116,0,0,0,93,0,0,0,0,0,0,1,144,0,0,1,140,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,1,0,0,0,0,0,0,0,216,16,42,17,0,0,0,0,180,0,0,0,36,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,148,0,0,0,0,0,0,0,0,0,0,0,108,0,0,0,28,0,0,0,95,255,255,3,0,0,0,0,1,0,0,0,28,0,0,0,0,0,0,0,88,0,0,0,48,0,2,0,0,0,1,0,0,0,0,0,56,0,0,0,72,67,111,108,111,114,0,171,171,0,1,0,3,0,1,0,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,115,95,51,95,48,0,50,46,48,46,49,49,54,50,54,46,48,0,171,0,0,0,0,0,0,0,36,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,16,1,196,0,34,0,0,0,200,143,192,0,0,192,192,0,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,1,244,16,42,17,1,0,0,1,40,0,0,0,204,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,0,0,0,0,212,0,0,0,28,0,0,0,198,255,254,3,0,0,0,0,3,0,0,0,28,0,0,0,0,0,0,0,191,0,0,0,88,0,2,0,8,0,4,0,0,0,0,0,100,0,0,0,116,0,0,0,180,0,2,0,4,0,4,0,0,0,0,0,100,0,0,0,116,0,0,0,185,0,2,0,0,0,4,0,0,0,0,0,100,0,0,0,116,80,114,111,106,101,99,116,105,111,110,0,171,0,3,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,105,101,119,0,87,111,114,108,100,0,118,115,95,51,95,48,0,50,46,48,46,49,49,54,50,54,46,48,0,171,171,0,0,0,0,0,0,0,204,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,2,144,0,0,0,3,16,1,16,3,0,0,18,0,194,0,0,0,0,0,96,4,96,10,18,0,18,0,0,0,0,0,0,0,0,3,196,0,34,0,0,0,5,248,0,0,0,0,6,136,0,0,0,0,200,1,0,1,0,167,167,0,175,0,0,0,200,2,0,1,0,167,167,0,175,0,1,0,200,4,0,1,0,167,167,0,175,0,2,0,200,8,0,1,0,167,167,0,175,0,3,0,200,1,0,0,0,167,167,0,175,1,4,0,200,2,0,0,0,167,167,0,175,1,5,0,200,4,0,0,0,167,167,0,175,1,6,0,200,8,0,0,0,167,167,0,175,1,7,0,200,1,128,62,0,167,167,0,175,0,8,0,200,2,128,62,0,167,167,0,175,0,9,0,200,4,128,62,0,167,167,0,175,0,10,0,200,8,128,62,0,167,167,0,175,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0 };
#endif

        private Effect PickingEffect;

        public RenderTarget2D RenderTarget;
        public RenderTarget2D PickerTarget;

        private SpriteBatch batch;

        BrainModel Cylinder;

        public PickingManager3D_Color()
        {
            Cylinder = ModelUtil.GenerateCylinderMesh(5, 1, 16);

            batch = new SpriteBatch(Engine.Instance.GraphicsDevice);

            int size = 512;
            RenderTarget = new RenderTarget2D(Engine.Instance.GraphicsDevice, size, size,
                false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);

            PresentationParameters pp = Engine.Instance.GraphicsDevice.PresentationParameters;
            PickerTarget = new RenderTarget2D(Engine.Instance.GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight,
                false, SurfaceFormat.Color, DepthFormat.Depth24);

            PickingEffect = new Effect(Engine.Instance.GraphicsDevice, effect);

            ShouldUpdate = true;
            ShouldDraw = true;
        }

        Vector3 CurrentPosition;
        public void Update()
        {



        }

        private void DrawBrainModel(BrainModel model)
        {
            GraphicsDevice device = Engine.Instance.GraphicsDevice;
            foreach (BrainModelMesh mesh in model.Meshes)
            {
                device.Indices = mesh.IndexBuffer;
                device.SetVertexBuffer(mesh.VertexBuffer);

                int count = this.PickingEffect.CurrentTechnique.Passes.Count;

                for (int p = 0; p < count; p++)
                {
                    PickingEffect.CurrentTechnique.Passes[p].Apply();

                    if (mesh.IndexBuffer == null)
                        device.DrawPrimitives(PrimitiveType.TriangleList, 0, mesh.PrimitiveCount);
                    else
                        device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
                            mesh.NumVertices, mesh.VertexOffset, mesh.PrimitiveCount);
                }
            }
        }

        float Terrain_Strength = 1;
        public void Draw()
        {
            if (Engine.Instance.RenderManager3D == null)
            {
                return;
            }

            ICamera3D camera = Engine.Instance.CameraManager.Camera3D;
            if (camera == null)
            {
                return;
            }
            
            GraphicsDevice device = Engine.Instance.GraphicsDevice;

            Vector2 mousePos = Engine.Instance.InputManager.GetMousePosition();
            int X = (int)mousePos.X;
            int Y = (int)mousePos.Y;
            if (X < 0 || Y < 0 ||
                X > device.Viewport.Width ||
                Y > device.Viewport.Height)
            {
                return;
            }

            if (Helper != null)
            {
                Helper.Update(X, Y, Engine.Instance.InputManager.IsMouseLeftDown(), Terrain_Strength);
                Helper.Draw();
            }

            IWorldObject wo_Mani = null;
            if (!Manipulating)
            {
                wo_Mani = Pick(X, Y, device.Viewport, camera, out UnitAxis);
                if (Engine.Instance.InputManager.IsMouseLeftDown())
                {
                    if (wo_Mani != null &&
                        wo_Mani != this.SelectedWorldObject)
                    {
                        this.SelectedWorldObject = wo_Mani;
                        if (OnSelected != null)
                            OnSelected(wo_Mani);
                    }
                }
            }

            Vector3 Position = Vector3.Zero;
            float size = 15;
            float RelativeScale = 5;
            if (this.SelectedWorldObject != null)
            {
                Position = SelectedWorldObject.Position;

                // Here, we calculate the Scale of the 3D Picker,
                // so it will always be of the same size,
                // doesn't matter the distance the user is from it
                if (!Manipulating)
                {
                    Vector3 viewPosition = camera.Position;

                    Matrix ScaleView = Matrix.CreateLookAt(Vector3.UnitZ *
                        Vector3.Distance(viewPosition, Position), Vector3.Zero, Vector3.Up);

                    Vector3 ProjStart = Engine.Instance.GraphicsDevice.Viewport.Project(
                        Vector3.Zero, camera.Projection, ScaleView, Matrix.Identity);
                    Vector3 ProjEnd = Engine.Instance.GraphicsDevice.Viewport.Project(
                        Vector3.UnitX, camera.Projection, ScaleView, Matrix.Identity);

                    RelativeScale = size / (ProjEnd - ProjStart).Length();

                    ScaleBefore = RelativeScale;
                }
                else
                {
                    RelativeScale = ScaleBefore;
                }

                if (Engine.Instance.InputManager.IsMouseLeftDown())
                {
                    Manipulating = true;

                    if (UnitAxis != Vector3.Zero)
                    {
                        Matrix Translation = SelectedWorldObject.WorldMatrix;
                        Matrix Projection = camera.Projection;
                        Matrix View = camera.View;
                        Viewport Viewport = Engine.Instance.GraphicsDevice.Viewport;
                        Vector2 Delta = Engine.Instance.InputManager.GetMouseDifference();

                        Vector3 StartPosition = Viewport.Project(Vector3.Zero, Projection, View, Translation);
                        Vector3 EndPosition = Viewport.Project(UnitAxis, Projection, View, Translation);

                        Vector3 ScreenDirection = Vector3.Normalize(EndPosition - StartPosition);
                        EndPosition = StartPosition + (ScreenDirection * (Vector3.Dot(new Vector3(Delta, 0f), ScreenDirection)));

                        StartPosition = Viewport.Unproject(StartPosition, Projection, View, Translation);
                        EndPosition = Viewport.Unproject(EndPosition, Projection, View, Translation);

                        Vector3 Difference = EndPosition - StartPosition;

                        switch (Mode)
                        {
                            case ManipulationMode3D.Translation:
                                SelectedWorldObject.Position += Difference * 5;
                                break;
                            case ManipulationMode3D.Scale:
                                SelectedWorldObject.Scale += Difference;
                                break;
                            case ManipulationMode3D.UniformScale:
                                SelectedWorldObject.Scale += new Vector3(Vector3Util.Average(Difference));
                                break;

                        }
                    }
                }
                else
                {
                    Manipulating = false;
                }
            }

            CurrentPosition = Position;

            device.SetRenderTarget(this.RenderTarget);
            device.Clear(Color.Transparent);
            IRenderManager3D renderManager = Engine.Instance.RenderManager3D;
            ICamera3D Camera = Engine.Instance.CameraManager.Camera3D;
            PickingEffect.Parameters["View"].SetValue(Camera.View);
            PickingEffect.Parameters["Projection"].SetValue(Camera.Projection);
            for (int i = 0; i < renderManager.Editor_Count(); i++)
            {
                IWorldObject wo = renderManager.Editor_GetWorldObject(i);

                PickingEffect.Parameters["World"].SetValue(wo.WorldMatrix);
                PickingEffect.Parameters["Color"].SetValue(GetColor(wo).ToVector3());
                if (wo.RenderingTag is BrainModel)
                {
                    BrainModel model = wo.RenderingTag as BrainModel;
                    DrawBrainModel(model);
                }
                if (wo.Model is BrainModel)
                {
                    BrainModel model = wo.Model as BrainModel;
                    DrawBrainModel(model);
                }
            }
            device.SetRenderTarget(null);

            device.SetRenderTarget(PickerTarget);
            device.Clear(Color.Transparent);

            if (SelectedWorldObject != null)
            {
                device.DepthStencilState = DepthStencilState.Default;

                float Nin = MathHelper.ToRadians(90);
                Matrix ScaleMatrix = Matrix.CreateScale(RelativeScale);
                PickingEffect.Parameters["World"].SetValue(ScaleMatrix * Matrix.CreateRotationX(Nin) * Matrix.CreateTranslation(CurrentPosition + new Vector3(0, 0, 2.5f * RelativeScale)));
                PickingEffect.Parameters["Color"].SetValue(new Vector3(0, 0, 1));
                DrawBrainModel(this.Cylinder);

                PickingEffect.Parameters["World"].SetValue(ScaleMatrix * Matrix.CreateTranslation(CurrentPosition + new Vector3(0, 2.5f * RelativeScale, 0)));
                PickingEffect.Parameters["Color"].SetValue(new Vector3(0, 1, 0));
                DrawBrainModel(this.Cylinder);

                PickingEffect.Parameters["World"].SetValue(ScaleMatrix * Matrix.CreateRotationZ(Nin) * Matrix.CreateTranslation(CurrentPosition - new Vector3(2.5f * RelativeScale, 0, 0)));
                PickingEffect.Parameters["Color"].SetValue(new Vector3(1, 0, 0));
                DrawBrainModel(this.Cylinder);
            }

            device.SetRenderTarget(null);
        }


        public void EndDraw()
        {
            batch.Begin();
            batch.Draw(this.PickerTarget, Vector2.Zero, Color.White);
            batch.End();
        }


        public IWorldObject Pick(int X, int Y, Viewport viewport, ICamera3D Camera, out Vector3 Axis)
        {
            IRenderManager3D renderManager = Engine.Instance.RenderManager3D;

            GraphicsDevice device= Engine.Instance.GraphicsDevice;
            Viewport view = device.Viewport;
            float xRatio = (float)this.RenderTarget.Width / (float)view.Width;
            float yRatio = (float)this.RenderTarget.Height / (float)view.Height;

            int x = IntUtil.Clamp((int)(X * xRatio), 0, RenderTarget.Width - 1);
            int y = IntUtil.Clamp((int)(Y * yRatio), 0, RenderTarget.Height - 1);
            Rectangle rect = new Rectangle(x, y, 1, 1);
            Color[] data = new Color[1];
            this.RenderTarget.GetData(0, rect, data, 0, 1);

            float xRatio2 = (float)this.PickerTarget.Width / (float)view.Width;
            float yRatio2 = (float)this.PickerTarget.Height / (float)view.Height;
            int x2 = IntUtil.Clamp((int)(X * xRatio2), 0, PickerTarget.Width - 1);
            int y2 = IntUtil.Clamp((int)(Y * yRatio2), 0, PickerTarget.Height - 1);
            Rectangle rect2 = new Rectangle(x2, y2, 1, 1);
            Color[] data2 = new Color[1];
            this.PickerTarget.GetData(0, rect2, data2, 0, 1);

            Color color = data[0];
            Color pickerColor = data2[0];
            Axis = Vector3.Zero;
            if (pickerColor == Color.Transparent)
            {
                for (int i = 0; i < renderManager.Editor_Count(); i++)
                {
                    IWorldObject wo = renderManager.Editor_GetWorldObject(i);

                    if (color == GetColor(wo))
                    {
                        Axis = Vector3.Zero;
                        return wo;
                    }
                }
            }

            Axis = pickerColor.ToVector3();

            return null;
        }

        public Color GetColor(IWorldObject wo)
        {
            if (wo.PickingTag == null)
            {
                if (lastPickColor.B < 255)
                {
                    lastPickColor.B++;
                }
                else
                {
                    if (lastPickColor.G < 255)
                    {
                        lastPickColor.G++;
                        lastPickColor.B = 0;
                    }
                    else
                    {
                        if (lastPickColor.R < 255)
                        {
                            lastPickColor.R++;
                            lastPickColor.G = 0;
                        }
                    }
                }

                wo.PickingTag = new Color(lastPickColor.R, lastPickColor.G,
                        lastPickColor.B);
            }
            Color c = (Color)wo.PickingTag;
            return c;
        }
        public TerrainEditorHelper Helper;
        public void EnableTerrainEditting()
        {
            if (this.SelectedWorldObject is TerrainWorldObject)
            {
                if (Helper != null)
                {
                    Helper.Dispose();
                }
                Helper = new TerrainEditorHelper(this.SelectedWorldObject as TerrainWorldObject);
            }
        }


        public void SetTerrainEdittingStrength(float strength)
        {
            this.Terrain_Strength = strength;
        }

        public void SetTerrainEdittingSize(float size)
        {
            if (this.Helper != null)
            {
                this.Helper.PickerSize = size;
            }
        }
    }
#endif
}
